package com.google.code.p.restrpc.directory.spring;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

import com.google.code.p.restrpc.directory.DefaultRegistry;
import com.google.code.p.restrpc.directory.Registry;
import com.google.code.p.restrpc.directory.RemoteServiceDefinition;
import com.google.code.p.restrpc.directory.RemoteServiceDefinitionPack;
import com.google.code.p.restrpc.directory.service.DirectoryService;

/**
 * @author dz
 */
public class DirectoryServiceFactoryBean implements
                                        FactoryBean<DirectoryService>,
                                        InitializingBean,
                                        DirectoryService,
                                        DisposableBean {

    public static final Registry getRegistry() {
        return registry;
    }
    
    private static DirectoryServiceFactoryBean instance;
    
    public static DirectoryServiceFactoryBean getInstance() {
        return instance;
    }
    
    private static Registry registry;
    
    private int heartbeat = 60 * 1000;
    
    /**
     * @return the heartbeat
     */
    public int getHeartbeat() {
        return heartbeat;
    }
    
    /**
     * @param heartbeat
     *            the heartbeat to set
     */
    public void setHeartbeat(int heartbeat) {
        this.heartbeat = heartbeat;
    }
    
    // **************FactoryBean**************
    public DirectoryService getObject() throws Exception {
        return this;
    }
    
    public Class<DirectoryService> getObjectType() {
        return DirectoryService.class;
    }
    
    public boolean isSingleton() {
        return true;
    }
    
    // ******************InitializingBean*******************
    public void afterPropertiesSet() throws Exception {
        registry = new DefaultRegistry(heartbeat);
        instance = this;
    }
    
    // *****************DisposableBean***************
    public void destroy() throws Exception {
        if (registry != null) {
            try {
                registry.shutdown();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    // *******************DirectoryService********************
    // all delegate to registry object
    public void disable(RemoteServiceDefinition rsd) {
        registry.disable(rsd);
    }
    
    public void enable(RemoteServiceDefinition rsd) {
        registry.enable(rsd);
    }
    
    public RemoteServiceDefinitionPack lookup(String serviceName,
                                              long lastModifiedMillis) {
        return registry.lookup(serviceName, lastModifiedMillis);
    }
    
    public RemoteServiceDefinitionPack lookup(String serviceName,
                                              String methodName,
                                              long lastModifiedMillis) {
        return registry.lookup(serviceName, methodName, lastModifiedMillis);
    }
    
    public void register(RemoteServiceDefinition rsd) {
        registry.register(rsd);
    }
    
    public void unregister(RemoteServiceDefinition rsd) {
        registry.unregister(rsd);
    }
    
    public boolean isRegistered(String address, int port) {
        return registry.isRegistered(address, port);
    }
    
    public void activate(String address, int port) {
        registry.activate(address, port);
    }
    
    public void unregisterAll(String address, int port) {
        registry.unregisterAll(address, port);
    }
    
}
